package com.darchrow.demo;

import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlXid;

import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author mdl
 * @date 2020/4/26 10:25
 */
public class Main {

    public static MysqlXADataSource getDataSource(String connectStr, String user, String pwd){
        try {
            MysqlXADataSource ds =new MysqlXADataSource();
            ds.setUrl(connectStr);
            ds.setUser(user);
            ds.setPassword(pwd);
            return  ds;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String connStr1 ="jdbc:mysql://localhost:3306/ymorder?serverTimezone=UTC&characterEncoding=utf-8";
        String connStr2 ="jdbc:mysql://localhost:3306/stock?serverTimezone=UTC&characterEncoding=utf-8";

        try {
            // 从不同的数据库获取数据源
            MysqlXADataSource ds1 =getDataSource(connStr1, "root", "123456");
            MysqlXADataSource ds2 =getDataSource(connStr2, "root", "123456");

            // 数据库1获取连接、资源管理器
            XAConnection xaConnection1 = ds1.getXAConnection();
            Connection connection1 = xaConnection1.getConnection();
            XAResource xaResource1 = xaConnection1.getXAResource();
            Statement statement1 = connection1.createStatement();

            // 数据库2获取连接、资源管理器
            XAConnection xaConnection2 = ds2.getXAConnection();
            Connection connection2 = xaConnection2.getConnection();
            XAResource xaResource2 = xaConnection2.getXAResource();
            Statement statement2 = connection2.createStatement();

            MysqlXid xid1 = new MysqlXid(new byte[]{0x01}, new byte[]{0x02}, 100);
            MysqlXid xid2 = new MysqlXid(new byte[]{0x01}, new byte[]{0x012}, 100);

            try {
                // 事务分支1通过资源管理器开启分支事务sql
                xaResource1.start(xid1, XAResource.TMNOFLAGS);
                int update1Result =statement1.executeUpdate("insert into ymorder.order(user_id, state, sku_id) values(2, 1, 999)");
                xaResource1.end(xid1, XAResource.TMSUCCESS);

                // 事务分支2通过资源管理器开启分支事务sql
                xaResource2.start(xid2, XAResource.TMNOFLAGS);
                int update2Result =statement2.executeUpdate("insert into stock.stock(sku_id, count) values(999, 1)");
                xaResource2.end(xid2, XAResource.TMSUCCESS);

                // 2PC,两阶段提交第一阶段
                int ret1 = xaResource1.prepare(xid1);
                int ret2 = xaResource2.prepare(xid2);

                // 事务协调者
                if(XAResource.XA_OK == ret1 && XAResource.XA_OK == ret2){
                    // 这里可能xaResource1成功，xaResource2失败
                    // 失败怎么办？记日志，去重试呗
                    xaResource1.commit(xid1, false);
                    xaResource2.commit(xid2, false);
                }else{
                    xaResource1.rollback(xid1);
                    xaResource2.rollback(xid2);
                }



            } catch (XAException e) {
                e.printStackTrace();
            }


        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }


    }
}
